package com.tvunetworks.center.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.tvunetworks.center.common.model.LoginUser;
import com.tvunetworks.center.common.model.SearchDeviceParam;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.gs.model.Device;
import com.tvunetworks.center.user.mapper.BookmarkDeviceMapper;
import com.tvunetworks.center.user.mapper.UserBookmarkMapper;
import com.tvunetworks.center.user.mapper.UserDeviceMapper;
import com.tvunetworks.center.user.model.BookmarkDevice;
import com.tvunetworks.center.user.model.BookmarkNameDevice;
import com.tvunetworks.center.user.model.ComparatorPostion;
import com.tvunetworks.center.user.model.UserBookmark;
import com.tvunetworks.center.user.model.json.VoBookmark;
import com.tvunetworks.center.user.model.json.VoDevice;
import com.tvunetworks.center.user.model.param.SearchBookmarkDeviceParam;
import com.tvunetworks.center.user.model.vo.PeerIdWithBookmarkId;
import com.tvunetworks.center.user.model.vo.SearchUserDeviceVo;
import com.tvunetworks.center.user.service.BookmarkDeviceService;
import com.tvunetworks.center.user.service.DeviceService;
import com.tvunetworks.center.user.service.UserBookmarkService;
import com.tvunetworks.center.user.service.UserDeviceService;
import com.tvunetworks.center.user.util.UserThreadPool;
import com.tvunetworks.center.user.util.UserUtil;
import lombok.extern.slf4j.Slf4j;
import net.spy.memcached.MemcachedClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.util.StringUtil;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * @program: tvucc-user
 * @description: BookmarkDeviceServiceImpl
 * @author lebronchen
 * @create: 2019-03-14 15:36
 **/
@Service
@Slf4j
public class BookmarkDeviceServiceImpl implements BookmarkDeviceService {

    @Autowired
    private BookmarkDeviceMapper bookmarkDeviceMapper;
    @Autowired
    @Qualifier("ccMemcacheClient")
    private MemcachedClient ccMemcacheClient;
    @Autowired
    private UserBookmarkService userBookmarkService;
    @Autowired
    private UserDeviceService userDeviceService;
    @Autowired
    private UserDeviceMapper userDeviceMapper;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private UserBookmarkMapper userBookmarkMapper;

    @Value("${ext.type}")
    private String extType;

    @Override
    public List<String> listUserPeerIdFilterByBookmarkAndCondition(String userId, SearchDeviceParam param) {
        List<String> peerIdsFilterByBookmark = new ArrayList<>();

        String condition = param.getCondition();

        if (param.isAllBookmark()) {
            // 选中所有书签，查询用户所有设备
            peerIdsFilterByBookmark = userDeviceService.listUserDevice(userId, condition, null);
        } else {
            // 查询书签下的设备
            if (StringUtils.isNotBlank(param.getBookmardIds())) {
                String[] bookmarkIds = param.getBookmardIds().split(",");
                if (bookmarkIds != null && bookmarkIds.length > 0) {
                    condition = MyUtil.formatCondition(condition);
                    List<String> bookmarkPeerIds = bookmarkDeviceMapper.listBookmarkPeerIds(Arrays.asList(bookmarkIds), condition);
                    if (bookmarkPeerIds != null && bookmarkPeerIds.size() > 0) {
                        peerIdsFilterByBookmark.addAll(bookmarkPeerIds);
                    }
                    List<String> tokenBookmarkPeerIds = bookmarkDeviceMapper.listBindedDeviceListForTokenByBookmarkIds(userId,
                            Arrays.asList(bookmarkIds), condition);
                    if (!CollectionUtils.isEmpty(tokenBookmarkPeerIds)) {
                        peerIdsFilterByBookmark.addAll(tokenBookmarkPeerIds);
                    }
                }
            }
        }
        // 查询未分类的设备
        if (param.isUnClassified()) {
            List<String> unclassifiedPeerIds = this.listUserUnClassifiedPeerIds(userId, condition, null);
            if (unclassifiedPeerIds != null && unclassifiedPeerIds.size() > 0) {
                peerIdsFilterByBookmark.addAll(unclassifiedPeerIds);
            }
        }
        return peerIdsFilterByBookmark;
    }

    @Override
    public List<String> listUserUnClassifiedPeerIds(String userId, String condition, List<String> typeList) {
        String types = UserUtil.packageDeviceTypesToString(typeList, extType);
        condition = MyUtil.formatCondition(condition);
        List<String> userAllPeerIds = userDeviceService.listUserDevice(userId, condition, types);
        if (userAllPeerIds == null || userAllPeerIds.size() == 0) {
            return null;
        }
        List<String> userInBookmarkPeerIds = bookmarkDeviceMapper.listUserInBookmarkPeerIds(userId, condition);
        if (userInBookmarkPeerIds != null && userInBookmarkPeerIds.size() > 0) {
            userAllPeerIds.removeAll(userInBookmarkPeerIds);
        }
        return userAllPeerIds;
    }

    @Override
    public Map<String, List<String>> listUserDeviceBookmarks(String userId, List<String> peerIds) {


        List<BookmarkNameDevice> bookmarkNameDevices = bookmarkDeviceMapper.listUserDeviceBookmarks(userId, peerIds);

        if(bookmarkNameDevices == null || bookmarkNameDevices.size() == 0){
            return new HashMap<>(0);
        }

        //用设备的Id 做key,bookmarks name 的集合做value
        Map<String, List<String>> collect = bookmarkNameDevices
                .stream()
                .collect(groupingBy(
                            BookmarkNameDevice::getPeerId,
                            Collectors.mapping(BookmarkNameDevice::getBookmarkName, Collectors.toList())
                        )
                );
        return collect;
    }

    /**
     *
     * @param userId userId
     * @param peerId peerId
     * @return List
     */
    public List<BookmarkDevice> listUserDeviceBookmarksByPeerId(String userId,String peerId){
       return bookmarkDeviceMapper.listUserDeviceBookmarksByPeerId(userId,peerId);
    }

    @Override
    @Transactional
    public void removeUserBookmarkDevice(List<String> userIds) {
        List<String> bookmarkDeviceIds = bookmarkDeviceMapper.listUserBookmarkDevice(userIds);
        if (bookmarkDeviceIds == null || bookmarkDeviceIds.size() == 0) {
            return;
        }
        bookmarkDeviceMapper.removeUserBookmarkDevice(bookmarkDeviceIds);
    }

    @Override
    @Transactional
    public void removeBookmarkDevice(String bookmarkId) {
        if (StringUtils.isBlank(bookmarkId)) {
            return;
        }
        BookmarkDevice record = new BookmarkDevice().setBookmarkId(bookmarkId);
        bookmarkDeviceMapper.delete(record);
    }

    @Override
    public void setBookmarkDeviceToMem() {
        UserThreadPool.SERVICETHREADPOOL.execute(() -> {
            List<PeerIdWithBookmarkId> list = bookmarkDeviceMapper.listPeerIdBookmarkId();
            if (CollectionUtils.isEmpty(list)) {
                return;
            }
            Map<String, List<String>> bdMap = new HashMap<>();
            for (PeerIdWithBookmarkId vo : list) {
                String bookmarkId = vo.getBookmarkId();
                String peerId = vo.getPeerId();
                List<String> pids = bdMap.get(bookmarkId);
                if (CollectionUtils.isEmpty(pids)) {
                    pids = new ArrayList<>();
                }
                pids.add(peerId);
                bdMap.put(bookmarkId, pids);
            }
            try {
                ccMemcacheClient.set("groupDeviceRelation", 0, bdMap);
            } catch (Exception e) {
                log.error(e.toString(), e);
            }
        });

    }

    @Override
    public List<SearchUserDeviceVo> listUnbindDevice(SearchBookmarkDeviceParam param) {
        UserBookmark userBookmark = userBookmarkService.getById(param.getBookmarkId());
        if (userBookmark == null) {
            return new ArrayList<>();
        }
        param.setAppendSql(param.appendTypeSql());
        param.setUserId(userBookmark.getUserId());

        String condition = param.getCondition();
        condition = MyUtil.formatCondition(condition);
        param.setCondition(condition);

        List<SearchUserDeviceVo> allList = bookmarkDeviceMapper.listUserAllPeerIds(param);
        if (CollectionUtils.isEmpty(allList)) {
            allList = new ArrayList<>();
        }
        //判断参数中是否选择token的选项
        boolean tokenFlag = param.isToken();
        //需要将token的查询放入allList中
        if(tokenFlag){
        	//查询当前登录用户下的token device设备
        	List<SearchUserDeviceVo> queryTokenDeviceList = null;
        	try {
				 queryTokenDeviceList = userDeviceMapper.queryTokenDeviceList(condition, userBookmark.getUserId());
			} catch (Exception e) {
				log.error(">>>>>>>>>>>listUnbindDevice(queryTokenDeviceList) is error{}",e);
			}
        	if(queryTokenDeviceList != null && queryTokenDeviceList.size() > 0){
        		List<SearchUserDeviceVo> retList = new ArrayList<SearchUserDeviceVo>();
        		allList.addAll(queryTokenDeviceList);
        		//去除重复
        		allList.stream().forEach(
                        p -> {
                            if (!retList.contains(p)) {
                            	retList.add(p);
                            }
                        }
                );
        	  allList = retList;
        	}
        }
        if(CollectionUtils.isEmpty(allList)){
        	return allList;
        }
        List<SearchUserDeviceVo> list = this.listBindedDevice(param);
        if (!CollectionUtils.isEmpty(list)) {
            allList.removeAll(list);
        }
        return allList;
    }

    /**
     *
     * @param userId userId
     * @param bookmarkId bookmarkId
     * @return List
     */
    public List<SearchUserDeviceVo> listBindedDeviceForToken(String userId,String bookmarkId){
        List<SearchUserDeviceVo> listBindTokenDevice = null;
        try {
            listBindTokenDevice = bookmarkDeviceMapper.listBindTokenDevice("",userId,bookmarkId);
        } catch (Exception e) {
            log.error(">>>>>>>>>>>>>>listBindedDevice(listBindTokenDevice) is error{}",e);
        }
        return listBindTokenDevice;
    }
    @Override
    public List<SearchUserDeviceVo> listBindedDevice(SearchBookmarkDeviceParam param) {
        UserBookmark userBookmark = userBookmarkService.getById(param.getBookmarkId());
        if (userBookmark == null) {
            return new ArrayList<>();
        }
        param.setAppendSql(param.appendTypeSql());
        param.setUserId(userBookmark.getUserId());

        String condition = param.getCondition();
        condition = MyUtil.formatCondition(condition);
        param.setCondition(condition);
        List<SearchUserDeviceVo> listBindedDevice = bookmarkDeviceMapper.listBindedDevice(param);
        //判断token的是否勾选,如果是勾选需要查询出绑定token device信息
        if(param.isToken()){
        	List<SearchUserDeviceVo> listBindTokenDevice = null;
        	try {
				listBindTokenDevice = bookmarkDeviceMapper.listBindTokenDevice(condition,userBookmark.getUserId(),param.getBookmarkId());
			} catch (Exception e) {
			   log.error(">>>>>>>>>>>>>>listBindedDevice(listBindTokenDevice) is error{}",e);
			}
        	if(listBindTokenDevice != null && listBindTokenDevice.size() > 0){
        		listBindedDevice.addAll(listBindTokenDevice);
        		List<SearchUserDeviceVo> retList = new ArrayList<SearchUserDeviceVo>();
        		//去除重复
        		listBindedDevice.stream().forEach(
                        p -> {
                            if (!retList.contains(p)) {
                            	retList.add(p);
                            }
                        }
                );
        		return retList;
        	}
        }
        return listBindedDevice;
    }

    @Override
    public List<SearchUserDeviceVo> listAllBindedDevice(String userId, String bookmarkId) {
        UserBookmark userBookmark = userBookmarkService.getById(bookmarkId);
        if (userBookmark == null) {
            return new ArrayList<>();
        }
        return bookmarkDeviceMapper.listUserBookmarkAllDevice(userId, bookmarkId);
    }

    @Override
    @Transactional
    public void correlateBookmarkDevice(String bookmarkId, String addPeerIds, String removePeerIds) {
        UserBookmark userBookmark = userBookmarkService.getById(bookmarkId);
        if (userBookmark == null) {
            return;
        }
        // 添加BookmarkDevice
        if (StringUtils.isNotBlank(addPeerIds)) {
            try {
                String[] peerIds = addPeerIds.split(",");
                for (String peerId : peerIds) {
                    BookmarkDevice bookmarkDevice = new BookmarkDevice()
                            .setBookmarkId(bookmarkId)
                            .setPeerId(peerId);
                    BookmarkDevice exist = bookmarkDeviceMapper.selectOne(bookmarkDevice);
                    if (exist != null) {
                        continue;
                    }
                    bookmarkDevice.setId(MyUtil.getUUID());
                    bookmarkDeviceMapper.insert(bookmarkDevice);
                }
            } catch (Exception e) {
                log.error(" bookmarkDeviceMapper.insert(bookmarkDevice) exception");
            }
        }
        // 移除BookmarkDevice
        if (StringUtils.isNotBlank(removePeerIds)) {
            String[] peerIds = removePeerIds.split(",");
            for (String peerId : peerIds) {
                BookmarkDevice bookmarkDevice = new BookmarkDevice()
                        .setBookmarkId(bookmarkId)
                        .setPeerId(peerId);
                BookmarkDevice exist = bookmarkDeviceMapper.selectOne(bookmarkDevice);
                if (exist == null) {
                    continue;
                }
                bookmarkDeviceMapper.delete(exist);
            }
        }

        this.setBookmarkDeviceToMem();
    }

    @Override
    @Transactional
    public void correlateDeviceBookmark(String bookmarkIds, String addPeerId, String removebookmarkIds,String bookmarkPid, String name,String userId) {
        String id = "";
       if(StringUtil.isNotEmpty(bookmarkPid) &&  StringUtil.isNotEmpty(name)){
           try {
               UserBookmark record = new UserBookmark()
                       .setUserId(userId)
                       .setBookmarkName(name)
                       .setParentId(bookmarkPid);
               List<UserBookmark> exist = userBookmarkMapper.select(record);
               id = MyUtil.getUUID();
               if (!CollectionUtils.isEmpty(exist)) {
                   // 书签名已存在
                   record.setBookmarkName(name+"_"+id.substring(0,3));
                   log.error("correlateDeviceBookmark bookmark exist");
               }
               record.setParentId(bookmarkPid);
               record.setId(id);
               userBookmarkMapper.insert(record);
               if(StringUtils.isNotEmpty(bookmarkIds)){
                   bookmarkIds = bookmarkIds+","+id;
               }else{
                   bookmarkIds=id;
               }
           } catch (Exception e) {
               log.error("userBookmarkMapper.insert(record)");
               return;
           }
       }
        // 添加BookmarkDevice
        if (StringUtils.isNotBlank(bookmarkIds)) {
            String[] bookmarkIdss = bookmarkIds.split(",");
            for (String bookmarkId : bookmarkIdss) {
                UserBookmark userBookmark = userBookmarkService.getById(bookmarkId);
                if (userBookmark == null) {
                    continue;
                }
                BookmarkDevice bookmarkDevice = new BookmarkDevice()
                        .setBookmarkId(bookmarkId)
                        .setPeerId(addPeerId);
                BookmarkDevice exist = bookmarkDeviceMapper.selectOne(bookmarkDevice);
                if (exist != null) {
                    continue;
                }
                bookmarkDevice.setId(MyUtil.getUUID());
                bookmarkDeviceMapper.insert(bookmarkDevice);
            }
        }
        // 移除BookmarkDevice
        if (StringUtils.isNotBlank(removebookmarkIds)) {
            String[] bookmarkIdss = removebookmarkIds.split(",");
            for (String bookmarkId : bookmarkIdss) {
                BookmarkDevice bookmarkDevice = new BookmarkDevice()
                        .setBookmarkId(bookmarkId)
                        .setPeerId(addPeerId);
                BookmarkDevice exist = bookmarkDeviceMapper.selectOne(bookmarkDevice);
                if (exist == null) {
                    continue;
                }
                bookmarkDeviceMapper.delete(exist);
            }
        }

        this.setBookmarkDeviceToMem();
    }

    @Override
    @Transactional
    public void moveBookmarkDevice(String fromBookmarkId, String toBookmarkIds, String peerIds) {
        this.correlateBookmarkDevice(fromBookmarkId, null, peerIds);
        this.correlateBookmarkDevice(toBookmarkIds, peerIds, null);
    }

    @Override
    public void removeBookmarkDeviceByPeerId(String peerId) {
        BookmarkDevice record = new BookmarkDevice().setPeerId(peerId);
        List<BookmarkDevice> existList = bookmarkDeviceMapper.select(record);
        if (CollectionUtils.isEmpty(existList)) {
            return;
        }
        for (BookmarkDevice bookmarkDevice : existList) {
            bookmarkDeviceMapper.delete(bookmarkDevice);
        }
    }


    @Override
    public int  copyDevice(String oldPeerId, String newPeerId, String taskId) {
        Device oldDevice = deviceService.getCurrentDevice(oldPeerId);
        if (oldDevice == null) {
            log.error("Start copyDevice copy BookmarkDevice failed oldPeerId not exist taskId:[{}] oldPeerId:[{}] newPeerId:[{}]", taskId, oldPeerId, newPeerId);
            return 1;
        }
        Device newDevice = deviceService.getCurrentDevice(newPeerId);
        if (newDevice == null) {
            log.error("Start copyDevice copy BookmarkDevice failed newPeerId not exist taskId:[{}] oldPeerId:[{}] newPeerId:[{}]", taskId, oldPeerId, newPeerId);
            return 2;
        }
        // 列出包含 old 不包含 new 的 bookmarkId，插入到 new 中
        List<String> bookmarkIds = bookmarkDeviceMapper.listBoomarkIdsInPeerId1NotInPeerId2(oldPeerId, newPeerId);
        if (CollectionUtils.isEmpty(bookmarkIds)) {
            log.error("Start copyDevice copy BookmarkDevice no changes need to copy taskId:[{}] oldPeerId:[{}] newPeerId:[{}]", taskId, oldPeerId, newPeerId);
            return 0;
        }
        List<BookmarkDevice> copyList = new ArrayList<>();
        for (String bookmarkId : bookmarkIds) {
            BookmarkDevice record = new BookmarkDevice()
                    .setPeerId(newPeerId)
                    .setBookmarkId(bookmarkId)
                    .setId(MyUtil.getUUID());
            copyList.add(record);
        }
        log.error("Start copyDevice copy BookmarkDevice need copy taskId:[{}] oldPeerId:[{}] newPeerId:[{}] copyList:[{}]", taskId, oldPeerId, newPeerId, copyList);
        int listSize = copyList.size();
        for (int i = 0; i < listSize; i+= 100) {
            int end = i + 100 > listSize ? listSize : i + 100;
            bookmarkDeviceMapper.insertList(copyList.subList(i, end));
        }
//        bookmarkDeviceMapper.insertList(copyList);
        return 0;
    }

    private List<VoDevice> getVoDeviceListFromPeerIdList(List<String> peerIdList) throws Exception {
        List<VoDevice> list = new ArrayList<VoDevice>();
        List<Device> deviceList = new ArrayList<Device>();
        for (String peerId : peerIdList) {
            Device device = deviceService.getCurrentDevice(peerId);
            if (device !=null){
                deviceList.add(device);
            }

        }
        sortList(deviceList);
        for (Device device : deviceList) {
            VoDevice voDevice = this.getVoDeviceFromDevice(device);
            list.add(voDevice);
        }
        return list;
    }
    // get Device from memcache
    private List<Device> getDeviceListFrompeerIdList(List<String> peerIdList) throws Exception {
        List<Device> deviceList = new ArrayList<Device>();
        for (String peerId : peerIdList) {
            Device device = deviceService.getCurrentDevice(peerId);
            if(device !=null){
                deviceList.add(device);
            }
        }
        sortList(deviceList);
        return deviceList;
    }
    // active: true-> getActiveNum false-> not
    private VoBookmark getVoBookmarkFromUserBookmark(UserBookmark bookmark, List<UserBookmark> bookmarkList, List<BookmarkDevice> bookmarkDeviceList, List<Device> deviceList, List<VoDevice> voDeviceList, String activeNum) throws Exception {
        List<VoDevice> voList = new ArrayList<VoDevice>();
        List<Device> dList = new ArrayList<Device>();
        VoBookmark voBookmark = new VoBookmark();
        voBookmark.setId(bookmark.getId());
        voBookmark.setName(bookmark.getBookmarkName());
        // set active online offline number
        if (StringUtils.equals("true", activeNum)) {
            setStatusNum(voBookmark, bookmark.getId(), bookmarkList, bookmarkDeviceList, voDeviceList);
        }

        if (bookmarkDeviceList != null && bookmarkDeviceList.size() > 0) {
            for (BookmarkDevice bookmarkDevice : bookmarkDeviceList) {
                if (StringUtils.equals(bookmarkDevice.getBookmarkId(), bookmark.getId())) {
                    if (deviceList != null && deviceList.size() > 0) {
                        for (Device device : deviceList) {
                            if (StringUtils.equals(bookmarkDevice.getPeerId(), device.getPeerId())) {
                                dList.add(device);
                            }
                        }
                    }
                }
            }
        }
        sortList(dList);
        log.error(" getAllChildBookmarkTreeWithDevice ==getVoBookmarkFromUserBookmark  dList:"+ JSON.toJSONString(dList));
        for (Device device : dList) {
            VoDevice voDevice = this.getVoDeviceFromDevice(device);
            log.error(" getAllChildBookmarkTreeWithDevice ==getVoBookmarkFromUserBookmark  device:"+ JSON.toJSONString(device));
            log.error(" getAllChildBookmarkTreeWithDevice ==getVoBookmarkFromUserBookmark  voDevice:"+ JSON.toJSONString(voDevice));
            voList.add(voDevice);
        }
        voBookmark.setReceiverList(voList);
        return voBookmark;
    }
    private void getAllChildBookmarkWithDevice(UserBookmark bookmark, List<UserBookmark> bookmarkList, VoBookmark lastVoBookmark, List<BookmarkDevice> bookmarkDeviceList, List<Device> deviceList, List<VoDevice> voDeviceList,
                                               String activeNum) throws Exception {
        for (UserBookmark nextBookmark : bookmarkList) {
            if (StringUtils.equals(lastVoBookmark.getId(), nextBookmark.getParentId())) {
                VoBookmark nextVoBookmark = getVoBookmarkFromUserBookmark(nextBookmark, bookmarkList, bookmarkDeviceList, deviceList, voDeviceList, activeNum);
                setChildVoBookmark(nextVoBookmark, lastVoBookmark);
                getAllChildBookmarkWithDevice(nextBookmark, bookmarkList, nextVoBookmark, bookmarkDeviceList, deviceList, voDeviceList, activeNum);
            }
        }
    }
    private VoDevice getVoDeviceFromDevice(Device device) {
        if (device != null) {
            return new VoDevice(device.getPeerId(), device.getName(), device.getStatus(), device.getVersion(), device.getIp(), device.getLivePeerId(), device.getLivePeerName());
        } else {
            return null;
        }
    }
    private void sortList(List<Device> list) {
        if (list != null && list.size() > 0) {
            for (Device device : list) {
                if (device.getStatus() != null && !device.getStatus().equals("")) {
                    if (device.getStatus().equals("22")) {
                        device.setPostion(1);
                    } else if (device.getStatus().equals("3")) {
                        device.setPostion(2);
                    } else if (device.getStatus().equals("2")) {
                        device.setPostion(3);
                    } else if (device.getStatus().equals("1")) {
                        device.setPostion(4);
                    } else if (device.getStatus().equals("0")) {
                        device.setPostion(5);
                    }
                } else {
                    device.setPostion(6);
                }
            }
        }
        if(list!=null && list.size()>0){
            Collections.sort(list, new ComparatorPostion());
        }
    }
    private void setStatusNum(VoBookmark voBookmark, String bookmarkId, List<UserBookmark> bookmarkList, List<BookmarkDevice> bookmarkDeviceList, List<VoDevice> voDeviceList) throws Exception {
        int activeNum = 0;
        int onlineNum = 0;
        int offlineNum = 0;
        List<UserBookmark> childList = new ArrayList<UserBookmark>();
        HashSet<VoDevice> voList = new HashSet<VoDevice>();
        if (bookmarkList != null && bookmarkList.size() > 0) {
            for (UserBookmark userBookmark : bookmarkList) {
                if (StringUtils.equals(bookmarkId, userBookmark.getId())) {
                    childList.add(userBookmark);
                }
            }
        }
        if(bookmarkList!=null  && bookmarkList.size() > 0){
            this.getAllChildBookmark(bookmarkId, bookmarkList, childList);
        }
        for (UserBookmark userBookmark : childList) {
            if (bookmarkDeviceList != null && bookmarkDeviceList.size() > 0) {
                for (BookmarkDevice bookmarkDevice : bookmarkDeviceList) {
                    if (StringUtils.equals(bookmarkDevice.getBookmarkId(), userBookmark.getId())) {
                        if (voDeviceList != null && voDeviceList.size() > 0) {
                            for (VoDevice voDevice : voDeviceList) {
                                if (StringUtils.equals(bookmarkDevice.getPeerId(), voDevice.getPeerId())) {
                                    voList.add(voDevice);
                                }
                            }
                        }
                    }
                }
            }
        }
        for (VoDevice voDevice : voList) {
            if (voDevice != null && "2".equals(voDevice.getStatus())) {
                activeNum++;
            }
            if (voDevice != null && "1".equals(voDevice.getStatus())) {
                onlineNum++;
            }
            if (voDevice != null && "0".equals(voDevice.getStatus())) {
                offlineNum++;
            }
        }
        voBookmark.setActiveNum(activeNum);
        voBookmark.setOnlineNum(onlineNum);
        voBookmark.setOfflineNum(offlineNum);
    }

    private void setChildVoBookmark(VoBookmark child, VoBookmark father) throws Exception {
        if (father != null) {
            List<VoBookmark> tempList = father.getBookmarkList();
            if (tempList != null && tempList.size() > 0) {
                father.getBookmarkList().add(child);
            } else {
                List<VoBookmark> tList = new ArrayList<VoBookmark>();
                tList.add(child);
                father.setBookmarkList(tList);
            }
        }
    }
    private void getAllChildBookmark(String bookmarkId, List<UserBookmark> bookmarkList, List<UserBookmark> reList) {
        for (UserBookmark userBookmark : bookmarkList) {
            if (StringUtils.equals(bookmarkId, userBookmark.getParentId())) {
                reList.add(userBookmark);
                getAllChildBookmark(userBookmark.getId(), bookmarkList, reList);
            }
        }
    }

    @Override
    public List<VoBookmark> getAllChildBookmarkTreeWithDevice(LoginUser user, String bookmarkId, String activeNum) throws Exception {
        List<VoBookmark> reList = new ArrayList<VoBookmark>();
        // get all child bookmark ids
        String childIds = null;
        List<String> idsList = null;
        idsList = bookmarkDeviceMapper.getAllChildBookmarkId(user.getId());
      /*  try {
            String  bookMarkIds ;
            childIds = bookmarkDeviceMapper.getAllChildBookmarkIds(bookmarkId,user.getId());
            log.error(" getAllChildBookmarkTreeWithDevice ==childIds:"+childIds);
            if( StringUtils.equals("0", bookmarkId) ){
                //root node not need
                if( childIds.length() < 4 ){
                    bookMarkIds= "";
                }else{
//                    bookMarkIds= (childIds.substring(4)).split(",");
                    bookMarkIds=  childIds.substring(4);
                }
            }else{
                bookMarkIds=  childIds.substring(2);
            }
            String [] ids=bookMarkIds.split(",");
            idsList =  Arrays.asList(ids);
        } catch (Exception e) {
            log.error("msg:{},e:{}",e.getMessage(),e);
        }*/
        // get all child bookmark list
        if (idsList.size()!=0) {
            List<UserBookmark> bookmarkList = bookmarkDeviceMapper.getAllChildBookmarkList(user.getId(), bookmarkId, idsList);

            log.error(" getAllChildBookmarkTreeWithDevice ==bookmarkList:" + JSON.toJSONString(bookmarkList));
            // get all child bookmarkDevice list
            List<BookmarkDevice> bookmarkDeviceList = bookmarkDeviceMapper.getAllChildBookmarkDeviceList(user.getId(), bookmarkId, idsList, "R");
            log.error(" getAllChildBookmarkTreeWithDevice ==bookmarkDeviceList:" + JSON.toJSONString(bookmarkDeviceList));
            // current peerIdList
            List<String> peerIdList = new ArrayList<String>();
            // get all child peerId list
            List<String> childPeerIdList = bookmarkDeviceMapper.getAllChildDevicePeerIdList(user.getId(), bookmarkId, idsList, "R");
            // if parent account exist,get all devices belong to parent account.
            String userParentId = user.getUserParentId();
            if (StringUtils.isNotBlank(userParentId) && "4".equals(user.getRole())) {//排除 admin的情况下，不需要过滤父级
                // parent account exist filter the devices that not exist in parent account.
                List<String> parentPeerIdList = bookmarkDeviceMapper.getBindTRPeerIdList(userParentId);
                if (parentPeerIdList != null && parentPeerIdList.size() > 0) {
                    for (String peerId : childPeerIdList) {
                        if (parentPeerIdList.contains(peerId)) {
                            peerIdList.add(peerId);
                        }
                    }
                }
            } else {
                // parent account don't exist
                peerIdList = childPeerIdList;
            }
            List<VoDevice> voDeviceList = this.getVoDeviceListFromPeerIdList(peerIdList);
            log.error(" getAllChildBookmarkTreeWithDevice ==voDeviceList:" + JSON.toJSONString(voDeviceList));
            List<Device> deviceList = this.getDeviceListFrompeerIdList(peerIdList);
            log.error(" getAllChildBookmarkTreeWithDevice ==deviceList:" + JSON.toJSONString(deviceList));

            if (bookmarkList != null && bookmarkList.size() > 0) {
                for (UserBookmark firstBookmark : bookmarkList) {
                    if (StringUtils.equals(bookmarkId, firstBookmark.getParentId())) {
                        VoBookmark voBookmark1 = getVoBookmarkFromUserBookmark(firstBookmark, bookmarkList, bookmarkDeviceList, deviceList, voDeviceList, activeNum);
                        reList.add(voBookmark1);
                        // recursion
                        getAllChildBookmarkWithDevice(firstBookmark, bookmarkList, voBookmark1, bookmarkDeviceList, deviceList, voDeviceList, activeNum);
                    }
                }
            }
        }
        return reList;
    }
    @Override
    public List<VoBookmark> getBookmarkShareAllChildBookmarkTreeWithDevice(LoginUser user, String bookmarkId, String activeNum) throws Exception {
        String parentId = userBookmarkMapper.selectParentId(user.getId());
        List<VoBookmark> reList = new ArrayList<VoBookmark>();
        // get all child bookmark ids
        String childIds = null;
        List<String> idsList = null;
        idsList = bookmarkDeviceMapper.getAllChildBookmarkId(parentId);
      /*  try {
            String  bookMarkIds ;
            childIds = bookmarkDeviceMapper.getAllChildBookmarkIds(bookmarkId,parentId);
            log.error(" getAllChildBookmarkTreeWithDevice ==childIds:"+childIds);
            if( StringUtils.equals("0", bookmarkId) ){
                //root node not need
                if( childIds.length() < 4 ){
                    bookMarkIds= "";
                }else{
//                    bookMarkIds= (childIds.substring(4)).split(",");
                    bookMarkIds=  childIds.substring(4);
                }
            }else{
                bookMarkIds=  childIds.substring(2);
            }
            String [] ids=bookMarkIds.split(",");
            idsList =  Arrays.asList(ids);
        } catch (Exception e) {
            log.error("msg:{},e:{}",e.getMessage(),e);
        }*/
        // get all child bookmark list
        if (idsList.size()!=0) {
            List<UserBookmark> bookmarkList = bookmarkDeviceMapper.getAllChildBookmarkList(parentId, bookmarkId, idsList);
            log.error(" getAllChildBookmarkTreeWithDevice ==bookmarkList:" + JSON.toJSONString(bookmarkList));
            // get all child bookmarkDevice list
            List<BookmarkDevice> bookmarkDeviceList = bookmarkDeviceMapper.getAllChildBookmarkDeviceList(user.getId(), bookmarkId, idsList, "R");
            log.error(" getAllChildBookmarkTreeWithDevice ==bookmarkDeviceList:" + JSON.toJSONString(bookmarkDeviceList));
            // current peerIdList
            List<String> peerIdList = new ArrayList<String>();
            // get all child peerId list
            List<String> childPeerIdList = bookmarkDeviceMapper.getAllChildDevicePeerIdList(user.getId(), bookmarkId, idsList, "R");
            // if parent account exist,get all devices belong to parent account.
            String userParentId = user.getUserParentId();
            if (StringUtils.isNotBlank(userParentId) && "4".equals(user.getRole())) {//排除 admin的情况下，不需要过滤父级
                // parent account exist filter the devices that not exist in parent account.
                List<String> parentPeerIdList = bookmarkDeviceMapper.getBindTRPeerIdList(userParentId);
                if (parentPeerIdList != null && parentPeerIdList.size() > 0) {
                    for (String peerId : childPeerIdList) {
                        if (parentPeerIdList.contains(peerId)) {
                            peerIdList.add(peerId);
                        }
                    }
                }
            } else {
                // parent account don't exist
                peerIdList = childPeerIdList;
            }
            List<VoDevice> voDeviceList = this.getVoDeviceListFromPeerIdList(peerIdList);
            log.error(" getAllChildBookmarkTreeWithDevice ==voDeviceList:" + JSON.toJSONString(voDeviceList));
            List<Device> deviceList = this.getDeviceListFrompeerIdList(peerIdList);
            log.error(" getAllChildBookmarkTreeWithDevice ==deviceList:" + JSON.toJSONString(deviceList));

            if (bookmarkList != null && bookmarkList.size() > 0) {
                for (UserBookmark firstBookmark : bookmarkList) {
                    if (StringUtils.equals(bookmarkId, firstBookmark.getParentId())) {
                        VoBookmark voBookmark1 = getVoBookmarkFromUserBookmark(firstBookmark, bookmarkList, bookmarkDeviceList, deviceList, voDeviceList, activeNum);
                        reList.add(voBookmark1);
                        // recursion
                        getAllChildBookmarkWithDevice(firstBookmark, bookmarkList, voBookmark1, bookmarkDeviceList, deviceList, voDeviceList, activeNum);
                    }
                }
            }
        }
        return reList;
    }
}
